<?php

namespace Yj\Watcher;

use Hyperf\Contract\ConfigInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Coroutine;
use Hyperf\Watcher\Driver\DriverInterface;
use Swoole\Coroutine\Channel;
use Yj\Watcher\Driver\ScanFileDriver;
use Symfony\Component\Console\Output\OutputInterface;


class YjWatcher
{

    /**
     * @var Options
     */
    protected $option;

    /**
     * @var ScanFileDriver
     */
    protected $driver;

    /**
     * @var OutputInterface
     */
    protected $output;


    /**
     * @Inject()
     * @var ConfigInterface
     */
    protected $config;

    public function __construct(Option $options, OutputInterface $output)
    {
        $this->option = $options;
        $this->driver = $this->getDriver();
        $this->output = $output;
        $this->channel = new Channel(1);
        $this->channel->push(1);
//        $this->config = $container->get(ConfigInterface::class);
    }

    public function getDriver()
    {
        return make(ScanFileDriver::class, ['option' => $this->option]);
    }

    public function run()
    {

        $this->reStart(false);
        $this->watchFile();

    }


    public function watchFile()
    {
        $channel = new Channel(1);
        Coroutine::create(function () use ($channel) {
            $this->driver->watch($channel);
        });
        while (true) {
            $pop = $channel->pop(1);

            if ($pop) {
                $this->output->writeln($pop);
                $this->reStart(true);
            }
        }
    }

    public function reStart($push = false)
    {

        //强杀
        Coroutine::create(function () use ($push) {
//            dump($this->channel->stats());

//            if($push){
//                $this->channel->push(1);
//            }

//            $pop = $this->channel->pop();
//            dump('pop='.$pop);

            $this->kill();
            $descriptorspec = [
                0 => STDIN,
                1 => STDOUT,
                2 => STDERR,
            ];

            dump('start server');


            proc_open("php ./bin/hyperf.php start", $descriptorspec, $pipes);

            $this->output->writeln('Stop server success.');


        });

    }


    public function kill()
    {
        $servers = array_column($this->config->get('server.servers'), 'port');

        $this->forceKill($servers);
    }

    function forceKill($servers)
    {
//        exec("php ./bin/hyperf.php server:stop");
        foreach ($servers as $server) {
            $command = "lsof -i :{$server}|grep -v \"PID\"|awk '{print \"kill -9\",$2}'|sh";

//            $command= "kill -9 $(netstat -tlnp | grep :{$server} | awk '{print $7}' | awk -F '/' '{print $1}')";
            dump($command);
            exec($command);

        }


    }
}